package com.lianjia.crawler.utils;

import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.Random;
import java.util.UUID;

/**
 * HTTP工具类，用于发送HTTP请求
 */
public class HttpUtils {
    private static final Logger logger = LoggerFactory.getLogger(HttpUtils.class);
    private static final int TIMEOUT = 10000; // 超时时间：10秒
    private static final Random random = new Random();
    
    // 模拟的浏览器信息
    private static final String[] SEC_CH_UA = {
        "\"Microsoft Edge\";v=\"137\", \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\""
    };
    
    private static final String[] SEC_CH_UA_PLATFORM = {
        "\"Windows\""
    };
    
    // 真实的Cookie
    private static final String REAL_COOKIE = "lianjia_uuid=eeced7d8-f1e1-489f-a6ca-88b5970837a4; crosSdkDT2019DeviceId=-49xy7r--g4wuqq-p9l323kk3x2ixh9-f83b46r92; _jzqc=1; Hm_lvt_46bf127ac9b856df503ec2dbf942b67e=1749044905; HMACCOUNT=3BFFE692CAA46FD4; _ga=GA1.2.1616326668.1749044923; _gid=GA1.2.1338662512.1749044923; _ga_654P0WDKYN=GS2.2.s1749044923$o1$g0$t1749044923$j60$l0$h0; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%221973b33462fc1a-0c17d29c14989-4c657b58-1327104-1973b33463010e9%22%2C%22%24device_id%22%3A%221973b33462fc1a-0c17d29c14989-4c657b58-1327104-1973b33463010e9%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_referrer%22%3A%22%22%2C%22%24latest_referrer_host%22%3A%22%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_utm_source%22%3A%22biying%22%2C%22%24latest_utm_medium%22%3A%22pinzhuan%22%2C%22%24latest_utm_campaign%22%3A%22wybeijing%22%2C%22%24latest_utm_content%22%3A%22biaotimiaoshu%22%2C%22%24latest_utm_term%22%3A%22biaoti%22%7D%7D; _ga_DX18CJBZRT=GS2.2.s1749044933$o1$g1$t1749046772$j60$l0$h0; _ga_EYZV9X59TQ=GS2.2.s1749044933$o1$g1$t1749046773$j60$l0$h0; _ga_KJTRWRHDL1=GS2.2.s1749046880$o1$g0$t1749046880$j60$l0$h0; _ga_QJN1VP0CMS=GS2.2.s1749046880$o1$g0$t1749046880$j60$l0$h0; _qzjc=1; ftkrc_=a235ee2b-1d43-4362-a6cc-12f0fcde0eec; lfrc_=2e551cf5-278e-464c-8a07-30c155050f89; _jzqckmp=1; select_city=310000; _ga_00MKBBEWEN=GS2.2.s1749142202$o1$g1$t1749142929$j54$l0$h0; lianjia_ssid=62fde8a8-936c-4056-a4ef-0e5fd743b45a; _jzqa=1.1640673054574399700.1749044905.1749169713.1749214094.4; _jzqx=1.1749044905.1749214094.4.jzqsr=cn%2Ebing%2Ecom|jzqct=/.jzqsr=sh%2Elianjia%2Ecom|jzqct=/ershoufang/pg98/; _ga_LRLL77SF11=GS2.2.s1749214106$o4$g1$t1749214168$j60$l0$h0; _ga_GVYN2J1PCG=GS2.2.s1749214106$o4$g1$t1749214168$j60$l0$h0; login_ucid=2000000244488749; lianjia_token=2.0012447183794d864203e958b29f579fbd; lianjia_token_secure=2.0012447183794d864203e958b29f579fbd; security_ticket=Jeao+0DBx6lSCpSNHBUchNepQjXl+aCvo/WoY5/BEAaCTvYwyluAI5GxMDxgYnGvURPlbenji11uIrzrFnzeiZVgkpCxRQKuJCppzaplm/1M6gym1uYTYDKoDql82VGnCC4PVauptK9/IkvdpTxhk1y+isDq35Rjbx65ZOEVFVE=; hip=hL-87iwwR_jXMUOFwVMyP1PhHMmELq7dfSUkUyLBmxo2b5PS7GJmsLh17LAZgutz55j5o04xIYtzSxWtlRXSoAt3vQFnlEdkkRLjd-tGN16tVkPtHlg9HflP_Sc4yf-cm3feBBIOHW_u05YAF7oD1BCBk24N67ZvuEPQCar6PrcOxIxdfdyto4eQpA%3D%3D; srcid=eyJ0Ijoie1wiZGF0YVwiOlwiMmYyNTJmZjQ3YTNmMzVhYTZiMGUxYzZhOTI3NjAxZDhjNmZhZDg2MDZmMjcyYzBhYjRkMGQxYmI4ZGYwMjljZDgzMjk2MmI5ZGJjYzU0NzI5MDM1MjVmZWRjOWJhNGViZTA3MjVmZjE1YTAxYTA2NGMxMzFhZGQzNjk1Yzk3Zjg4YjVlZTZjZDFjNTYyYjQ0YWUyY2VjNjY2ODMxMTllYjJkYjVkOTFmZjBiZjE0OGEyNTUzODkwMWE2ZGJiMmI4M2VkMmRlMmExM2I1ZTVlNzcyOWI0ZWQ5MWNlYjlkOGI3NWViNDNlOGVlMTZlMjg3MjJkZTc1ZjY5M2Y4MTI5YTliMDc2N2NjYWQ1NjZkYTdmNzhjZjM1ZmRjZTkwYzE2MzRkYjI4ZGZhNmNiOTc4NzQwYTA2NjkyZWZhZmVkZDNcIixcImtleV9pZFwiOlwiMVwiLFwic2lnblwiOlwiYzBlNmY2N2RcIn0iLCJyIjoiaHR0cHM6Ly9zaC5saWFuamlhLmNvbS9lcnNob3VmYW5nLyIsIm9zIjoid2ViIiwidiI6IjAuMSJ9; Hm_lpvt_46bf127ac9b856df503ec2dbf942b67e=1749214483; _qzja=1.293484253.1749046899260.1749169712569.1749214094144.1749214477530.1749214483221.0.0.0.77.4; _qzjb=1.1749214094144.4.0.0.0; _qzjto=46.2.0; _jzqb=1.4.10.1749214094.1";
    
    /**
     * 获取HTML内容
     *
     * @param url 目标URL
     * @param userAgent 用户代理
     * @param referer 来源URL
     * @return HTML内容
     */
    public static String getHtml(String url, String userAgent, String referer) {
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        
        try {
            // 创建HttpClient
            httpClient = HttpClients.createDefault();
            
            // 创建HttpGet请求
            HttpGet httpGet = new HttpGet(url);
            
            // 设置请求配置
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(TIMEOUT)
                    .setSocketTimeout(TIMEOUT)
                    .setConnectionRequestTimeout(TIMEOUT)
                    .build();
            httpGet.setConfig(requestConfig);
            
            // 设置请求头，完全模拟用户提供的请求头
            httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Edg/137.0.0.0");
            httpGet.setHeader("Referer", referer);
            httpGet.setHeader("Accept", "application/json, text/javascript, */*; q=0.01");
            httpGet.setHeader("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6");
            httpGet.setHeader("Accept-Encoding", "gzip, deflate, br, zstd");
            httpGet.setHeader("Connection", "keep-alive");
            httpGet.setHeader("sec-ch-ua", "\"Microsoft Edge\";v=\"137\", \"Chromium\";v=\"137\", \"Not/A)Brand\";v=\"24\"");
            httpGet.setHeader("sec-ch-ua-mobile", "?0");
            httpGet.setHeader("sec-ch-ua-platform", "\"Windows\"");
            httpGet.setHeader("Sec-Fetch-Dest", "empty");
            httpGet.setHeader("Sec-Fetch-Mode", "cors");
            httpGet.setHeader("Sec-Fetch-Site", "same-origin");
            httpGet.setHeader("X-Requested-With", "XMLHttpRequest");
            
            // 使用真实Cookie
            httpGet.setHeader("Cookie", REAL_COOKIE);
            
            // 执行请求
            logger.info("发送请求: {}", url);
            response = httpClient.execute(httpGet);
            
            // 获取响应状态码
            int statusCode = response.getStatusLine().getStatusCode();
            logger.info("响应状态码: {}", statusCode);
            
            if (statusCode == HttpStatus.SC_OK) {
                // 获取响应实体
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    String html = EntityUtils.toString(entity, "UTF-8");
                    logger.info("成功获取HTML，长度: {}", html.length());
                    return html;
                }
            } else if (statusCode == HttpStatus.SC_FORBIDDEN || statusCode == 429) {
                // 403 Forbidden 或 429 Too Many Requests，可能是被反爬机制拦截
                logger.warn("请求被拦截，状态码: {}", statusCode);
                // 等待一段时间后重试
                try {
                    int waitTime = 30000 + random.nextInt(30000); // 30-60秒
                    logger.info("等待 {} 毫秒后重试", waitTime);
                    Thread.sleep(waitTime);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            } else {
                logger.warn("请求失败，状态码: {}", statusCode);
            }
        } catch (IOException e) {
            logger.error("请求出错: {}", e.getMessage(), e);
        } finally {
            // 关闭资源
            try {
                if (response != null) {
                    response.close();
                }
                if (httpClient != null) {
                    httpClient.close();
                }
            } catch (IOException e) {
                logger.error("关闭资源失败: {}", e.getMessage(), e);
            }
        }
        
        return null;
    }
    
    /**
     * 下载图片
     *
     * @param url 图片URL
     * @param userAgent 用户代理
     * @param referer 来源URL
     * @return 图片数据
     */
    public static byte[] downloadImage(String url, String userAgent, String referer) {
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        
        try {
            // 创建HttpClient
            httpClient = HttpClients.createDefault();
            
            // 创建HttpGet请求
            HttpGet httpGet = new HttpGet(url);
            
            // 设置请求配置
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(TIMEOUT)
                    .setSocketTimeout(TIMEOUT)
                    .setConnectionRequestTimeout(TIMEOUT)
                    .build();
            httpGet.setConfig(requestConfig);
            
            // 设置请求头
            httpGet.setHeader("User-Agent", userAgent);
            httpGet.setHeader("Referer", referer);
            httpGet.setHeader("Accept", "image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8");
            httpGet.setHeader("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6");
            httpGet.setHeader("Accept-Encoding", "gzip, deflate, br, zstd");
            httpGet.setHeader("Connection", "keep-alive");
            httpGet.setHeader("sec-ch-ua", SEC_CH_UA[random.nextInt(SEC_CH_UA.length)]);
            httpGet.setHeader("sec-ch-ua-mobile", "?0");
            httpGet.setHeader("sec-ch-ua-platform", SEC_CH_UA_PLATFORM[random.nextInt(SEC_CH_UA_PLATFORM.length)]);
            httpGet.setHeader("Sec-Fetch-Dest", "image");
            httpGet.setHeader("Sec-Fetch-Mode", "no-cors");
            httpGet.setHeader("Sec-Fetch-Site", "same-site");
            
            // 使用真实Cookie
            httpGet.setHeader("Cookie", REAL_COOKIE);
            
            // 执行请求
            logger.info("下载图片: {}", url);
            response = httpClient.execute(httpGet);
            
            // 获取响应状态码
            int statusCode = response.getStatusLine().getStatusCode();
            logger.info("响应状态码: {}", statusCode);
            
            if (statusCode == HttpStatus.SC_OK) {
                // 获取响应实体
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    byte[] imageData = EntityUtils.toByteArray(entity);
                    logger.info("成功下载图片，大小: {} 字节", imageData.length);
                    return imageData;
                }
            } else {
                logger.warn("下载图片失败，状态码: {}", statusCode);
            }
        } catch (IOException e) {
            logger.error("下载图片出错: {}", e.getMessage(), e);
        } finally {
            // 关闭资源
            try {
                if (response != null) {
                    response.close();
                }
                if (httpClient != null) {
                    httpClient.close();
                }
            } catch (IOException e) {
                logger.error("关闭资源失败: {}", e.getMessage(), e);
            }
        }
        
        return null;
    }
} 